#ifndef CANVAS_H
#define CANVAS_H

#include <cstdio>
#include <ctime>

#include <map>

#include <QWidget>
#include <QtOpenGL>
#include <QGLWidget>
#include <QTabletEvent>
#include <QFileDialog>
#include <QImage>
#include <QString>


#include "TuioListener.h"
#include "TuioClient.h"
#include "TuioObject.h"
#include "TuioCursor.h"

#include "cursor.h"
#include "trace.h"
#include "key.h"

using namespace TUIO;

class Scene;
class Interpreter;

class Canvas{

    protected:
        Scene *scene;        
        map<int,Trace> traces;
        
        Interpreter *interpreter;

    public:
        Canvas();
        ~Canvas();

        Scene *getScene();

        bool onApplication(Cursor &c);
        
        void setViewport(int _left, int _top, int _width, int _height);
        void setWindow(float _left, float _right, float _bottom, float _top);
        
        virtual void offCursor(Cursor &c){};
        virtual void onNearCursor(Cursor &c){};
        virtual void onPressCursor(Cursor &c){};
        virtual void onMoveCursor(Cursor &c){};
        virtual void onReleaseCursor(Cursor &c){};
        
        virtual void onPressKey(int key){};
        virtual void onReleaseKey(int key){};        
        
        virtual void initialize()=0;
        virtual void resizeCanvas(int width, int height)=0;
        virtual void paint()=0;
};

class QGLCanvas : public QGLWidget , public Canvas{
    private:
        int idTimer;
        int interval;

        void keyPressEvent(QKeyEvent *event);
        void keyReleaseEvent(QKeyEvent *event);
        
        void paintGL();
        void initializeGL();
        void resizeGL(int width, int height);
        
    protected:
        void timerEvent(QTimerEvent *event);

    public:
        QGLCanvas();
        ~QGLCanvas();

        void setInterval(int interval);

        void saveImage();
};

class TabletCanvas : public QGLCanvas {
    private:
        bool near;

        void tabletEvent(QTabletEvent *event);
        void inputListener(Cursor &cursor);
        
    protected:
        int traceId;

    public:
        TabletCanvas();
        ~TabletCanvas();
};

class WimpCanvas : public QGLCanvas {
    private:
        void mousePressEvent(QMouseEvent *event);
        void mouseMoveEvent(QMouseEvent *event);
        void mouseReleaseEvent(QMouseEvent *event);
        
    protected:
        int traceId;

    public:
        WimpCanvas();
        ~WimpCanvas();
};

class TuioCanvas : public QGLCanvas, public TuioListener {
    private:
        TuioClient *tuioClient;

        void addTuioObject(TuioObject *tobj);
        void updateTuioObject(TuioObject *tobj);
        void removeTuioObject(TuioObject *tobj);
        void addTuioCursor(TuioCursor *tcur);
        void updateTuioCursor(TuioCursor *tcur);
        void removeTuioCursor(TuioCursor *tcur);
        
        void refresh(TuioTime packetTime){};
        

    protected:
        int traceId;

    public:
        TuioCanvas();
        ~TuioCanvas();
};

#endif /* CANVAS_H */
